Source code for error_handling_f90

"""
Fortran module error_handling:September 2016

Error handling and reporting module. Exceptional program
conditions (errors) can be signaled, detected, and handled
or reported to the user accordingly.

**Details**

Although more advanced error tracking and error handling
strategies are possible with this class, we suggest as best-practice
the definition of a few macros as shortcuts to the error handling.
But these macros allow lazy programmers to create and propagate
errors with the least possible effort. These macros are defined as
one liners on top of the corresponding modules:

``#define RAISE_ERROR(MSG)
call signal_error(error, __LINE__, __FILE__, MSG, proc_name); return``

``#define TRACK_ERROR(X)
if(detect_error(X)) call signal_error(X, __LINE__, __FILE__, '');
if(detect_error(X)) return``
"""

[docs] class error_type(): """ Runtime error signal **Class variables** desc : character(:), allocatable Optional error description. e.g., context. loc : character(:), allocatable Location where the error occured, e.g. (sub)program name. Subsequent error (causal follow-up error(s) in recursion caused by this one). Shall be nullified if error has not caused any subsequent error. Usually of generic SubError_type, but further specializations are possible. Note: As long as alloc. recursion not fully available, we use a pointer queue with proper deep-copy and finalization methods """
[docs] def error_deep_copy_to(self): """ fortran-subroutine - Deep copy of an error. **Arguments** this : error_type, in Make a copy of the error `this` copy : error_type, out Must be of same or extended class than `this`. As Error_type is baseclass, this will work for any extended Error type, but it will not copy any of the error's extended components. On exit, holds the copy of `this`. **Details** Copies recursively error and sub-errors into compatible type variable. Should be overwritten by extensions! """ return
[docs] def error_get_desc(self): """ fortran-function - Get error description string **Arguments** this : error_type, in Obtain the description of the error contained in `this`. **Result** desc : character(:) Set to description. If no description set, returns a notification. """ return
[docs] def error_get_loc(self): """ fortran-function - **Arguments** this : error_type, in Return the location of the error contained in `this`. **Result** loc : character(:) Set to location. If no location set, returns a notification. **Details** Get error location string. """ return
[docs] def error_get_name(self): """ fortran-function - Return the error's identifIer **Arguments** this : error_type, in Get the name of the error contained in `this`. **Result** name : character(:) Set to the class name of the error. """ return
[docs] def error_has_sub(self): """ fortran-function - Check if error has subsequent errors **Arguments** this : error_type, in Return boolean flag if `this` has sub errors. **Result** has_sub : logical Set to true, if sub-errors are present. Otherwise false. """ return
[docs] def error_load_signal(self): """ fortran-subroutine - Load error into signal handle. **Arguments** this : error_type, in this : loaded onto the signal., in error : error_type, inout Signal handle. Replaced by `this` on exit. Signals allocated on entry will be cleared. **Details** Default Error_type clears the signal and copies itself into it. Extensions may behave differently, e.g. append (SubError_type) """ return
[docs] class suberror_type(error_type): """ Subsequent error signals an unhandled error condition. """
[docs] def suberror_load_signal(self): """ fortran-subroutine - Load error into signal handle **Arguments** this : SubError_type, in this : loaded onto the signal., in error : error_type, inout Signal handle. If clean on input, replaced by `this` on exit. Othwerwise, `this` is appended as last 'sub'-component to the existing error. """ return
[docs] class valueerror_type(error_type): """ Error signals that describe various exceptional program conditions. """
[docs] class memoryerror_type(error_type): """ No documentation extracted. **Class variables** status_value = 0 : integer Status value from the allocation call, i.e, the internal status flag could take value of corrupt allocation status (/= 0). """
[docs] def memoryerror_print_desc(self): """ fortran-subroutine - Print a formatted description to output unit for an memory error. **Arguments** this : memoryerror_type, in Print a description of the error contained in `this`. unit : integer, optional, in Unit to print error report. Default to std-error unit. """ return
[docs] class arithmeticerror_type(error_type): """ Baseclass for all errors during arithmetic operations. """
[docs] class ioerror_type(error_type): """ Baseclass for all I/O transfer errors. **Class variables** status_value = 0 : integer Contains the status value of the iostat call unit_name : character(:), allocatable filename, or unit identifier. """
[docs] def ioerror_get_unit_name(self): """ fortran-function - Obtain the unit name of the file handle. \reuslt unit_name unit_name is character(:) Unit name of the IO error. **Arguments** this : IOError_type, in Get the unit name associated with the error `this`. """ return
[docs] def ioerror_print_desc(self): """ fortran-subroutine - Print a formatted description to output unit for an IO error. **Arguments** this : ioerror_type, in Print a description of the error contained in `this`. unit : integer, optional, in Unit to print error report. Default to std-error unit. """ return
[docs] def signal_error_full(): """ fortran-subroutine - ?? (ft) Signal an exceptional program condition (error). **Arguments** error (optional) : error_type, optional, inout Error signal handle into which the 'new_error' is loaded by it's `load_signal` method. If 'error' is not present, the `no_handle_action` will be triggered. line_number : integer, in Line number of the error, intended to be provided by preprocessor macro __LINE__ filename : character(*), in Filename where the error occurs, intended to be provided by macro __FILE__ new_error : error_type, in The error to be signaled. The user should provide it with a description of the context and circumstances of the exceptional condition that is signaled. Depending on it's 'load_error' method, it modifies the error. The `new_error` is usually copied. This allows to provide the `new_error` in an expression, such as a derived-type constructor, e.g. `signal_error(..., ValueError_type("..."))`. proc_name : character(*), optional, in name of the affected function/subroutine. This location will be part of the displayed message in error reports, and serves as a trace to the part of the code where the error occured. no_handle_action : character, optional, in Can be either 'N' for nothing, 'R' for report and continue, or 'S' for report and stop. If not provided, the module-wide ErrorHandling_no_handle_action is used. **Details** Indicate that a specified error has occured at a given location. The error will be loaded on the signal in an error-specific way (e.g. replace signal, append to existing errors, etc., see `load_signal`) """ return
[docs] def signal_error_macro(): """ fortran-subroutine - July 2021 (dj) Signal an unspecified error allowing on to specify line number and filename. **Arguments** error : error_type, optional, inout error handling class to track error. line_number : integer, in Line number of the error, intended to be provided by preprocessor macro __LINE__ filename : character(*), in Filename where the error occurs, intended to be provided by macro __FILE__ desc : character(*), in description of the error, i.e., error message. proc_name : character(*), optional, in name of the affected function/subroutine. This location will be part of the displayed message in error reports, and serves as a trace to the part of the code where the error occured. no_handle_action : character, optional, in Can be either 'N' for nothing, 'R' for report and continue, or 'S' for report and stop. If not provided, the module-wide ErrorHandling_no_handle_action is used. """ return
[docs] def stop_on_error(): """ fortran-subroutine - Stop program on active error. **Arguments** error : error_type, allocatable, optional, in Check if error was set and exit program. **Details** Stops with error exit-code and reports error if active. If signal is clean, nothing is done. """ return
[docs] def detect_error(): """ fortran-function - **Arguments** error : error_type, allocatable, optional, in Check this error type if currently an error is present **Result** detected : logical detected : present and allocated with an error. **Details** Check if error is present in signal """ return
[docs] def clear_error(): """ fortran-subroutine - ?? (ft) Clear all errors from signal **Arguments** error : error_type, allocatable, optional, inout Reset this error into a clean state. **Details** Resets signal-handle into a clean state. Any signaled errors will become deleted from the handle. Use after resolving an error, or to signal a higher priority error instead that would otherwise get appended as sub-error. """ return
[docs] def load_error(): """ fortran-subroutine - Load error into signal **Arguments** error : error_type, allocatable, optional, inout Loads provided error into signal, if signal-handle present. See `Error_type%load_signal` new_error : error_type, in Combining new error into previous one `error`. **Details** The subroutine is useful when dealing with multiple (local) signal handles """ return
[docs] def report_error(): """ fortran-subroutine - **Arguments** error : error_type, allocatable, optional, in Error to be reported. unit : integer, optional, in Unit to print error report. Default to std-error unit. **Details** Print error report to output unit Prints a formatted report of an active error and all subsequent errors. Nothing is done if signal-handle is not present or signal is clean. The report starts with a header, followed by a cronologically ordered list of error locations and formatted descriptions, starting with this error, followed by it's subsequent errors. """ return
[docs] def get_error_unit(): """ fortran-function - ?? **Arguments** unit : integer, optional., in If present, the returned error output unit is set to unit as module variable `ErrorHandling_error_unit`. **Result** err_unit : integer Either `unit` if present or default unit defined **Details** Returns module-wide default error output unit """ return
[docs] def error_append_sub(): """ fortran-subroutine - **Arguments** this : error_type, inout Append another error as suberror to `this`. sub : error_type, in Appends deep copy of `sub` in the list of subsequent errors of `this`. **Details** Append subsequent error. """ return
[docs] def error_final(): """ fortran-subroutine - Finalization of an error in the sense of deallocating it. **Arguments** this : error_type, inout Deallocate all memory allocated for `this`, i.e., Clean up pointer components, here 'sub' errors. """ return
[docs] def error_print_desc(): """ fortran-subroutine - Print a formatted description to output unit. **Arguments** this : error_type, in Print a description of the error contained in `this`. unit : integer, optional, in Unit to print error report. Default to std-error unit. **Details** Extensions shall briefly state their specific information incl. 'desc' The location is printed separately as a header information. """ return
[docs] def error_print_report(): """ fortran-subroutine - **Arguments** this : error_type, in Print formatted report of the complete error contained in `this`. unit : integer, optional, in Unit to print error report. Default to std-error unit. **Details** Print error report to output unit. Includes a header/preamble with the location, followed by the description. Prints the report of subsequent error(s) separated by a blank line. The report always ends with one blank line. """ return
[docs] def error_create(): """ fortran-function - Constructor for error instance. **Arguments** desc : character(:), in Description by the user to describe the error. **Result** error : error_type Create an error when given the description `desc`. """ return
[docs] def suberror_create(): """ fortran-function - Constructor for SubError instance. **Arguments** desc : character(:), in Description by the user to describe the suberror. **Result** error : suberror_type Create a suberror when given the description `desc`. """ return
[docs] def valueerror_create(): """ fortran-function - Constructor for ValueError instance. **Arguments** desc : character(:), in Description by the user to describe the value error. **Result** error : valueerror_type Create a value error when given the description `desc`. """ return
[docs] def memoryerror_create(): """ fortran-function - Constructor for MemoryError instance. **Arguments** desc : character(:), in Description by the user to describe the memory error. **Result** error : memoryerror_type Create a memory error when given the description `desc`. """ return
[docs] def arithmeticerror_create(): """ fortran-function - Constructor for ArithmeticError instance. **Arguments** desc : character(:), in Description by the user to describe the arithmetic error. **Result** error : arithmeticerror_type Create a arithmetic error when given the description `desc`. """ return
[docs] def ioerror_from_unit_name(): """ fortran-function - Constructor for an IOError. **Arguments** desc : character(:), in Text description of the error. status_value : integer, optional, in Status value of the io-call. unit_number : integer, optional, in Unit of the filehandle. **Result** error : IOError_type Initialized error. """ return
[docs] def ioerror_from_unit_number(): """ fortran-function - Create and infer unit name from number, unit must be opened and named. **Arguments** desc : character(:), in Text description of the error. status_value : integer, optional, in Status value of the io-call. unit_number : integer, in Unit of the filehandle. **Result** error : IOError_type Initialized error. **Details** Use only if a file/unit-name is not accessible otherwise. """ return